﻿// -----------------------------------------------------------------------
// <copyright file="VariableLength7BitEncoded{T}.cs" company="none">
// Copyright (c) 2012 M. Alberti, xanatos(at)live.it
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
// </copyright>
// -----------------------------------------------------------------------

namespace FluentSerializer.CollectionsHelpers
{
    using System.Linq.Expressions;
    using System.Reflection;
    using FluentSerializer.Utilities;

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class VariableLength7BitEncoded<T> : ICollectionHelper
    {
        /// <summary>
        /// 
        /// </summary>
        protected static readonly MethodInfo Read = typeof(BinaryStreamEx).GetMethod("Read7BitEncoded", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(BinaryReaderStream) }, null);

        /// <summary>
        /// 
        /// </summary>
        protected static readonly MethodInfo Write = typeof(BinaryStreamEx).GetMethod("Write7BitEncoded", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(BinaryWriterStream), typeof(long) }, null);

        /// <summary>
        /// 
        /// </summary>
        protected static readonly MethodInfo SizeOf = typeof(BinaryStreamEx).GetMethod("SizeOf7BitEncoded", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(long) }, null);

        #region IFluentSerializerCollectionHandler Members

        /// <summary>
        /// 
        /// </summary>
        public bool IsUniversal
        {
            get { return true; }
        }

        /// <summary>
        /// 
        /// </summary>
        public bool IsFixedLength
        {
            get { return false; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public Expression DeserializeLength(Expression reader, Expression length)
        {
            return Expression.ConvertChecked(Expression.Call(Read, reader), typeof(int));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public Expression SerializeLength(Expression writer, Expression length)
        {
            return Expression.Call(Write, writer, Expression.Convert(length, typeof(long)));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public Expression SizeLength(Expression length)
        {
            return Expression.Call(SizeOf, Expression.Convert(length, typeof(long)));
        }

        #endregion
    }
}